﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ls.Utils
{
    public static class  IntegerExt
    {
        #region Loops
        ///// <summary>
        ///// 循环迭代action，从0到ndx.
        ///// </summary>
        ///// <param name="ndx">迭代次数( 从0开始 )</param>
        ///// <param name="action">调用的方法</param>
        //public static void Times(this int ndx, Action<int> action)
        //{
        //    for (int i = 0; i < ndx; i++)
        //    {
        //        action(i);
        //    }
        //}


        /// <summary>
        /// 循环迭代action，从start到end.
        /// </summary>
        /// <param name="start">开始的数字.</param>
        /// <param name="end">结束的数字（不包括）</param>
        /// <param name="action">调用的方法</param>
        public static void Upto(this int start, int end, Action<int> action)
        {
            for (int i = start; i < end; i++)
            {
                action(i);
            }
        }


        /// <summary>
        /// 循环迭代action，从start到end.
        /// </summary>
        /// <param name="start">开始的数字.</param>
        /// <param name="end">结束的数字（包括）</param>
        /// <param name="action">调用的方法</param>
        public static void UptoIncluding(this int start, int end, Action<int> action)
        {
            for (int i = start; i <= end; i++)
            {
                action(i);
            }
        }


        /// <summary>
        /// 循环迭代action，从start到end.（递减）
        /// </summary>
        /// <param name="end">结束的数字</param>
        /// <param name="start">开始的数字（不包括）.</param>
        /// <param name="action">调用的方法</param>
        public static void Downto(this int end, int start, Action<int> action)
        {
            for (int i = end; i > start; i--)
            {
                action(i);
            }
        }


        /// <summary>
        /// 循环迭代action，从start到end.（递减）
        /// </summary>
        /// <param name="end">结束的数字</param>
        /// <param name="start">开始的数字（包括）.</param>
        /// <param name="action">调用的方法</param>
        public static void DowntoIncluding(this int end, int start, Action<int> action)
        {
            for (int i = end; i >= start; i--)
            {
                action(i);
            }
        }
        #endregion


        #region Math
        /// <summary>
        /// 是否是奇数
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static bool IsOdd(this int num)
        {
            return num % 2 != 0;
        }


        /// <summary>
        /// 是否是偶数
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static bool IsEven(this int num)
        {
            return num % 2 == 0;
        }
        #endregion

  
        #region Dates
        /// <summary>
        /// 判断是否是闰年
        /// </summary>
        /// <param name="year"></param>
        /// <returns></returns>
        public static bool IsLeapYear(this int year)
        {
            return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
        }


        /// <summary>
        /// 取得多少天以前的时间
        /// </summary>
        /// <param name="days">数字（几天之前）</param>
        /// <returns></returns>
        public static DateTime DaysAgo(this int days)
        {
            return DateTime.Now.AddDays(-days);
        }


        /// <summary>
        /// 取得多少月以前的时间
        /// </summary>
        /// <param name="months">数字（几月之前）</param>
        /// <returns></returns>
        public static DateTime MonthsAgo(this int months)
        {
            return DateTime.Now.AddMonths(-months);
        }


        /// <summary>
        /// 取得多少年以前的时间
        /// </summary>
        /// <param name="years">数字（几年之前）</param>
        /// <returns></returns>
        public static DateTime YearsAgo(this int years)
        {
            return DateTime.Now.AddYears(-years);
        }


        /// <summary>
        /// 取得多少小时以前的时间
        /// </summary>
        /// <param name="hours">Number of hours ago</param>
        /// <returns></returns>
        public static DateTime HoursAgo(this int hours)
        {
            return DateTime.Now.AddHours(-hours);
        }


        /// <summary>
        /// 取得多少分钟以前的时间
        /// </summary>
        /// <param name="minutes">Number of minutes ago</param>
        /// <returns></returns>
        public static DateTime MinutesAgo(this int minutes)
        {
            return DateTime.Now.AddMinutes(-minutes);
        }


        /// <summary>
        /// 取得多少天以后的时间
        /// </summary>
        /// <param name="days">天数</param>
        /// <returns></returns>
        public static DateTime DaysFromNow(this int days)
        {
            return DateTime.Now.AddDays(days);
        }


        /// <summary>
        /// 取得多少月以后的时间
        /// </summary>
        /// <param name="months">月数</param>
        /// <returns></returns>
        public static DateTime MonthsFromNow(this int months)
        {
            return DateTime.Now.AddMonths(months);
        }


        /// <summary>
        /// 取得多少年以后的时间
        /// </summary>
        /// <param name="years">年数</param>
        /// <returns></returns>
        public static DateTime YearsFromNow(this int years)
        {
            return DateTime.Now.AddYears(years);
        }


        /// <summary>
        /// 取得多少小时以后的时间
        /// </summary>
        /// <param name="hours">小时数</param>
        /// <returns></returns>
        public static DateTime HoursFromNow(this int hours)
        {
            return DateTime.Now.AddHours(hours);
        }


        /// <summary>
        /// Gets the datetime from now + minutes supplied
        /// </summary>
        /// <param name="minutes">Number of minutes from now</param>
        /// <returns></returns>
        public static DateTime MinutesFromNow(this int minutes)
        {
            return DateTime.Now.AddMinutes(minutes);
        }
        #endregion


        #region Time
        /// <summary>
        /// Converts the number to days as a TimeSpan.
        /// </summary>
        /// <param name="num">Number representing days</param>
        /// <returns></returns>
        public static TimeSpan Days(this int num)
        {
            return new TimeSpan(num, 0, 0, 0);
        }


        /// <summary>
        /// Converts the number to hours as a TimeSpan
        /// </summary>
        /// <param name="num">Number representing hours</param>
        /// <returns></returns>
        public static TimeSpan Hours(this int num)
        {
            return new TimeSpan(0, num, 0, 0);
        }


        /// <summary>
        /// Converts the number of minutes as a TimeSpan
        /// </summary>
        /// <param name="num">Number representing minutes</param>
        /// <returns></returns>
        public static TimeSpan Minutes(this int num)
        {
            return new TimeSpan(0, 0, num, 0);
        }


        /// <summary>
        /// Converts the number to seconds as a TimeSpan
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static TimeSpan Seconds(this int num)
        {
            return new TimeSpan(0, 0, 0, num);
        }


        /// <summary>
        /// 转换为TimeSpan
        /// </summary>
        /// <param name="num">Number reprsenting a timespan</param>
        /// <returns></returns>
        public static TimeSpan Time(this int num)
        {
            return Time(num, false);
        }



        /// <summary>
        /// 转换为TimeSpan
        /// </summary>
        /// <param name="num"></param>
        /// <param name="convertSingleDigitsToHours">Indicates whether to treat "9" as 9 hours instead of minutes.</param>
        /// <returns></returns>
        public static TimeSpan Time(this int num, bool convertSingleDigitsToHours)
        {
            TimeSpan time = TimeSpan.MinValue;
            if (convertSingleDigitsToHours)
            {
                if (num <= 24)
                    num *= 100;
            }
            int hours = num / 100;
            int hour = hours;
            int minutes = num % 100;

            time = new TimeSpan(hours, minutes, 0);
            return time;
        } 
        #endregion


        #region Hexadecimal and binary 
        /// <summary>
        /// 转换为16进制
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static string ToHex(this int number)
        {
            return Convert.ToString(number, 16);
        }


        /// <summary>
        /// 转换为2进制
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static string ToBinary(this int number)
        {
            return Convert.ToString(number, 2);
        }
        #endregion
    }
}
